package com.qiusuo0226.platform.config;

import com.alibaba.fastjson2.JSON;
import com.qiusuo0226.mvc.config.property.WebMvcProperty;
import com.qiusuo0226.platform.interceptor.TokenInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.*;

import java.util.Set;

/**
 * SpringMVC相关配置
 * @author qiusuo
 * @date 2023/3/29 10:51
 */
@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private WebMvcProperty webMvcProperty;

    /**
     * 注入自定义拦截器
     */
    @Autowired
    private TokenInterceptor tokenInterceptor;


    /**
     * todo 添加方法拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Token校验拦截器配置
        Set<String> interceptorTokenPaths = webMvcProperty.getInterceptorTokenPaths();
        String[] interceptorTokenPathsArray = null != interceptorTokenPaths ? interceptorTokenPaths.toArray(new String[interceptorTokenPaths.size()]) : new String[0];

        log.debug("token拦截路径:{}", JSON.toJSONString(interceptorTokenPathsArray));
        // 注册自定义拦截器
        registry.addInterceptor(tokenInterceptor)
                // 拦截的路径
                .addPathPatterns(interceptorTokenPathsArray)
                // 不拦截的路径
                .excludePathPatterns();

    }

    /**
     * todo 添加视图路由
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // ViewController 请求路径 ViewName 视图名称
        registry.addViewController("login").setViewName("index");
        registry.addViewController("index").setViewName("index");
        registry.addViewController("demo").setViewName("demo");
    }

    /**
     * todo 跨域处理
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        WebMvcProperty.Cros crosProperty = webMvcProperty.getCros();
        CorsRegistration corsRegistration = registry.addMapping(crosProperty.getAllowedPathPattern())
                // 允许携带cookie进行跨域
                .allowCredentials(crosProperty.isAllowCredentials());

        // 允许所有请求ip,port跨域
        // 若allowCredentials(true) 则不能是使用.allowedOrigins("*") 需要使用 .allowedOriginPatterns("*")
        if (StringUtils.equals(CorsConfiguration.ALL, crosProperty.getAllowedOrigin())) {
            corsRegistration.allowedOriginPatterns(CorsConfiguration.ALL);
        } else {
            if (StringUtils.isNotBlank(crosProperty.getAllowedOrigin())) {
                corsRegistration.allowedOriginPatterns(crosProperty.getAllowedOrigin().split(","));
            }
        }

        // 支持所有请求方式(get,post,put,...)
        if (StringUtils.equals(CorsConfiguration.ALL, crosProperty.getAllowedMethod())) {
            corsRegistration.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS");
        } else {
            if (StringUtils.isNotBlank(crosProperty.getAllowedMethod())) {
                corsRegistration.allowedMethods(crosProperty.getAllowedMethod().split(","));
            }
        }

        // 允许请求头中的header，默认都支持
        if (StringUtils.equals(CorsConfiguration.ALL, crosProperty.getAllowedHeader())) {
            corsRegistration.allowedHeaders(CorsConfiguration.ALL);
        } else {
            if (StringUtils.isNotBlank(crosProperty.getAllowedHeader())) {
                corsRegistration.allowedHeaders(crosProperty.getAllowedHeader().split(","));
            }
        }

        // 响应头中允许访问的header，默认为空
        if (StringUtils.equals(CorsConfiguration.ALL, crosProperty.getExposedHeader())) {
            corsRegistration.exposedHeaders(CorsConfiguration.ALL);
        } else {
            if (StringUtils.isNotBlank(crosProperty.getExposedHeader())) {
                corsRegistration.exposedHeaders(crosProperty.getExposedHeader().split(","));
            }
        }

        // 预请求的结果的有效期，默认30分钟,这里为1小时
        corsRegistration.maxAge(crosProperty.getMaxAge());
    }

    /**
     * todo 资源加载
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/");
    }
}
